home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / metamail / richmail / richset.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-21  |  5.1 KB  |  222 lines

  1. /*-------------------------------------------------------------------------
  2.  
  3.   richset.c - Handling for different character sets in richtext.
  4.  
  5.   Copyright (c) 1992 Rhys Weatherley
  6.  
  7.   Permission to use, copy, modify, and distribute this material
  8.   for any purpose and without fee is hereby granted, provided
  9.   that the above copyright notice and this permission notice
  10.   appear in all copies, and that the name of Rhys Weatherley not be
  11.   used in advertising or publicity pertaining to this
  12.   material without specific, prior written permission.
  13.   RHYS WEATHERLEY MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR
  14.   SUITABILITY OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED
  15.   "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
  16.  
  17.   Revision History:
  18.   ================
  19.  
  20.    Version  DD/MM/YY  By  Description
  21.    -------  --------  --  --------------------------------------
  22.      1.0    21/06/92  RW  Original Version of richset.c
  23.  
  24.   You may contact the author by:
  25.   =============================
  26.  
  27.    e-mail: rhys@cs.uq.oz.au
  28.      mail: Rhys Weatherley
  29.        5 Horizon Drive
  30.        Jamboree Heights
  31.        Queensland 4074
  32.        Australia
  33.  
  34. -------------------------------------------------------------------------*/
  35.  
  36. #include <stdio.h>
  37. #include "richlex.h"
  38. #include "richset.h"
  39.  
  40. /*
  41.  * Define a list of all character set processors in memory.
  42.  */
  43. static    struct    charsetproc    *CharacterSets[] =
  44.       {&usascii_charset,
  45.        &iso2022_charset,
  46.        NULL};
  47.  
  48. /*
  49.  * Global data for this module.
  50.  */
  51. #define    MAX_CHAR_SETS    100
  52. static    int    NumCharSets=0;
  53. static    struct    charsetproc    *CharSets[MAX_CHAR_SETS];
  54. static    int    CharEncStack[MAX_CHAR_SETS];
  55.  
  56. /*
  57.  * Initialise the stack of character set processors, starting with
  58.  * a particular base processor.  The initialisation function of all
  59.  * character set processors is called.
  60.  */
  61. charsetinit (charset,name)
  62. struct    charsetproc *charset;
  63. char    *name;
  64. {
  65.     int temp = 0;
  66.     CharSets[0] = charset;
  67.     NumCharSets = 1;
  68.     while (CharacterSets[temp]) {
  69.         (*(CharacterSets[temp] -> init))
  70.         ((CharacterSets[temp] == charset ? name : NULL));
  71.     ++temp;
  72.     }
  73. }
  74.  
  75. /*
  76.  * Initialise the stack, starting with a character set processor with
  77.  * a particular name.
  78.  */
  79. charsetnameinit    (name)
  80. char    *name;
  81. {
  82.     int temp = 0;
  83.     int succeed = 0;
  84.     char *temp1,*temp2;
  85.     struct charsetproc *charset = &usascii_charset;
  86.     while (!succeed && CharacterSets[temp]) {
  87.     temp2 = CharacterSets[temp] -> names;
  88.     while (!succeed && *temp2) {
  89.         temp1 = name;
  90.         while (*temp1 && *temp2 && *temp2 != ':' && *temp2 == *temp1) {
  91.         ++temp1;
  92.         ++temp2;
  93.         }
  94.         if (*temp1 == '\0' && (*temp2 == '\0' || *temp2 == ':')) {
  95.         succeed = 1;
  96.         charset = CharacterSets[temp];
  97.         }
  98.         while (*temp2 && *temp2 != ':') {
  99.         ++temp2;
  100.         }
  101.         if (*temp2 == ':') {
  102.         ++temp2;
  103.         }
  104.     }
  105.     ++temp;
  106.     }
  107.     charsetinit (charset,name);
  108. }
  109.  
  110. /*
  111.  * Push a new character set processor onto the stack.
  112.  */
  113. charsetpush (charset)
  114. struct    charsetproc *charset;
  115. {
  116.     if (NumCharSets >= MAX_CHAR_SETS) {
  117.         fprintf (stderr,"Too many nested character sets: aborting\n");
  118.     exit (1);
  119.     } else {
  120.     CharEncStack[NumCharSets - 1] = RichtextCharEncoding;
  121.     (*(CharSets[NumCharSets - 1] -> encoding)) (-1); /* Leave current */
  122.         CharSets[NumCharSets++] = charset;
  123.     }
  124. }
  125.  
  126. /*
  127.  * Pop the top-most character set processor off the stack
  128.  * if it matches the given processor.  Note: the base
  129.  * processor is never popped off.
  130.  */
  131. charsetpop (charset)
  132. struct    charsetproc *charset;
  133. {
  134.     if (NumCharSets > 1 && CharSets[NumCharSets - 1] == charset) {
  135.         --NumCharSets;
  136.     richtextencoding (CharEncStack[NumCharSets - 1]);
  137.     (*(CharSets[NumCharSets - 1] -> encoding)) (RichtextCharEncoding);
  138.     }
  139. }
  140.  
  141. /*
  142.  * See if the character set processor on the top of the stack
  143.  * matches the given processor.
  144.  */
  145. int    charsettop (charset)
  146. struct    charsetproc *charset;
  147. {
  148.     if (NumCharSets > 1) {
  149.     return (CharSets[NumCharSets - 1] == charset);
  150.     } else {
  151.     return (0);
  152.     }
  153. }
  154.  
  155. /*
  156.  * Set the details for a character set member in the top-most
  157.  * character set.
  158.  */
  159. charmember (member,ch)
  160. struct    charsetmember *member;
  161. RCHAR    ch;
  162. {
  163.     member -> ch = ch;
  164.     member -> charset = CharSets[NumCharSets - 1];
  165. }
  166.  
  167. /*
  168.  * Set the details for a member of a specific character set.
  169.  */
  170. charmemberspec (member,ch,charset)
  171. struct    charsetmember *member;
  172. RCHAR    ch;
  173. struct    charsetproc *charset;
  174. {
  175.     member -> ch = ch;
  176.     member -> charset = charset;
  177. }
  178.  
  179. /*
  180.  * Set the details for a output control code character.
  181.  */
  182. charmemberctrl (member,ch)
  183. struct    charsetmember *member;
  184. RCHAR    ch;
  185. {
  186.     member -> ch = ch;
  187.     member -> charset = NULL;
  188. }
  189.  
  190. /*
  191.  * Attempt to process a richtext command by passing it to the
  192.  * "command" function of all character set processors.  Returns
  193.  * zero if the command was not processed.
  194.  */
  195. int    charsetcommand (token,negated)
  196. char    *token;
  197. int    negated;
  198. {
  199.     int temp = 0;
  200.     while (CharacterSets[temp]) {
  201.         if ((*(CharacterSets[temp] -> command)) (token,negated))
  202.         return (1);
  203.     ++temp;
  204.     }
  205.     return (0);
  206. }
  207.  
  208. /*
  209.  * Test for an extension singleton command.
  210.  */
  211. int    charsetsingle (token)
  212. char    *token;
  213. {
  214.     int temp = 0;
  215.     while (CharacterSets[temp]) {
  216.         if ((*(CharacterSets[temp] -> single)) (token))
  217.         return (1);
  218.     ++temp;
  219.     }
  220.     return (0);
  221. }
  222.